home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <ctype.h>
- #include <sys/stat.h>
- #include <limits.h>
- #include <signal.h>
- #include "netconf.h"
- #include "../xconf/xconf.h"
- #include "netconf.m"
-
- /*
- Return != 0 if a file is missing or do not contain any configuration
- line. A file containing only comments is considered empty.
-
- configuration file use \ for continuation and # for comments.
- */
- int file_empty (const char *fpath)
- {
- int ret = 1;
- FILE *fin = fopen (fpath,"r");
- if (fin != NULL){
- char buf[2000];
- while (fgets_strip(buf,sizeof(buf)-1,fin,NULL)!=NULL){
- char *pt = buf;
- while (isspace(*pt)) pt++;
- if (*pt != '\0'){
- ret = 0;
- break;
- }
- }
- fclose (fin);
- }
- return ret;
- }
- /*
- Information on how to manage and start a daemon (generally network)
- To avoid repetition in subclasses, the destructor received no argument
- and the init function complete the setup, so the object must always
- be created and init() immediatly after. This is all done in
- daemon_new().
- */
- PUBLIC DAEMON::DAEMON ()
- {
- name = NULL;
- path = NULL;
- args = NULL;
- next = NULL;
- managed = override = 0;
- }
- /*
- Information on how to manage and start a daemon (generally network)
- */
- PUBLIC void DAEMON::init (
- int _managed,
- const char *_name,
- const char *buf,
- DAEMON *_next)
- {
- next = _next;
- managed = (char)_managed;
- char tmp[PATH_MAX];
- char *pttmp = tmp;
- while (*buf > ' ') *pttmp++ = *buf++;
- *pttmp = '\0';
- if (pttmp > tmp){
- name = strdup (_name);
- path = strdup (tmp);
- buf = str_skip(buf);
- args = strdup (buf);
- }
-
- }
-
- PUBLIC VIRTUAL DAEMON::~DAEMON ()
- {
- free (name);
- free (path);
- free (args);
- }
- /*
- Return != 0 if this is a valid record.
- */
- PUBLIC int DAEMON::isok()
- {
- return name != NULL;
- }
-
-
- /*
- Execute a command using the shell with loging in /tmp/netconf.log
- */
- int netconf_system (const char *cmd)
- {
- /* #Specification: netconf / starting daemons / log
- The file /var/adm/netconf.log is updated each time netconf
- start or stop a daemon.
- */
- net_prtlog (MSG_U(X_EXECUTING,"Executing :%s\n"),cmd);
- int ret = 0;
- if (!simul_ison()){
- int old_uid = getuid();
- int old_euid = geteuid();
- setuid (old_euid);
- ret = system (cmd);
- setreuid (old_uid,old_euid);
- net_prtlog (" return %d\n",ret);
- }
- return ret;
- }
- /*
- Execute a command using the shell with loging in /tmp/netconf.log
- The name of the command is used to located more info in /etc/conf.daemons.
-
- The command is conditionally executed if netconf is allowed to
- managed this command.
- */
- int netconf_system_if (const char *name, const char *args)
- {
- int ret = -1;
- DAEMON *dae = daemon_find (name);
- if (dae != NULL){
- ret = 0;
- char buf[1000];
- sprintf (buf,"%s %s",dae->getpath(),args);
- if (dae->is_managed()){
- ret = netconf_system(buf);
- }else if (!simul_ison()){
- net_prtlog (MSG_U(X_WOULDEXEC,"Would have executed :%s\n"),buf);
- }
- }
- return ret;
- }
- /*
- Execute a command using the shell.
- Return 0 if ok, != 0 if any error.
-
- This function is there to allows extension such as loging, debugging
- etc.
- */
- PUBLIC int DAEMON::system(const char *cmd)
- {
- return netconf_system (cmd);
- }
-
- /*
- start the daemon without much questionning.
- Return -1 if any error.
- */
- PUBLIC VIRTUAL int DAEMON::start()
- {
- int ret = 0;
- if (!exist()){
- if (!simul_ison()){
- net_prtlog (MSG_U(X_MISSWOULDHAVE,"Program missing: Would have started %s\n")
- ,name);
- }
- }else{
- char buf[2000];
- sprintf (buf,"%s %s",path,args);
- ret = system (buf);
- }
- return ret;
- }
- /*
- Stop a daemon if it is running with a given signal number.
- Return -1 if any error, -2 if no process alive, 0 if signal sent
- */
- PUBLIC int DAEMON::signal(
- int signal_num,
- const char *msg,
- const char *sem_file) // File used to remember when we
- // did issued the last signal
- // Or NULL if we don't care
- {
- int ret = -2;
- PROC *prc = process_find (path);
- if (prc != NULL){
- if (simul_ison()){
- ret = 0;
- }else{
- ret = prc->kill (signal_num);
- if (sem_file != NULL){
- int fd = creat (sem_file,0666);
- if (fd != -1) close (fd);
- }
- }
- net_prtlog (MSG_U(X_SIGNALING,"%s %s with signal %d return %d\n")
- ,msg,path,signal_num,ret);
- }
- return ret;
- }
- /*
- Stop a daemon if it is running with a given signal number.
- Return -1 if any error, -2 if no process alive, 0 if signal sent
- */
- PUBLIC int DAEMON::signal(
- int signal_num,
- const char *msg)
- {
- return signal(signal_num,msg,NULL);
- }
-
- /*
- Stop a daemon if it is running with a given signal number.
- Return -1 if any error.
- */
- PUBLIC int DAEMON::kill(int signal_num)
- {
- int ret = 0;
- for (int i=1; i<=3; i++){
- if (process_find(path)==NULL){
- break;
- }else if (i==1){
- ret = signal (signal_num,"Killing");
- if (ret == -2 || simul_ison()) break;
- }
- sleep(i);
- process_read();
- }
- return ret;
- }
- /*
- Stop a daemon if it is running.
-
- The default is to use signal SIGTERM. This function is virtual.
- Return -1 if any error.
- */
- PUBLIC VIRTUAL int DAEMON::stop()
- {
- return kill (SIGTERM);
- }
- /*
- A daemon may be restart normally by killing it and starting it.
- It may be different for some daemon...
-
- Return -1 if any error.
- */
- PUBLIC VIRTUAL int DAEMON::restart()
- {
- int ret = stop();
- if (ret != -1) ret = start();
- return ret;
- }
-
- /*
- Start or stop a daemon depending of the content of a configuration file.
- If the file is younger than the process, the process is restarted.
- */
- PUBLIC int DAEMON::startif_file (const char *fname)
- {
- long date = file_date (fname);
- if (date != -1){
- int empty = file_empty(fname);
- if (empty) date = -1;
- }
- return startif_date (date);
- }
- /*
- Start or stop a daemon depending of the content of a configuration file.
- If the file is younger than the process, the process is restarted.
- */
- PUBLIC int DAEMON::startif_file (const CONFIG_FILE &cfile)
- {
- return startif_file (cfile.getpath());
- }
- /*
- Restart, start or stop a daemon if he is older than a date.
- If the date is <= 0, it means that the corresponding configuration
- file do not exist or is empty, so the daemon must be stopped.
- */
- PUBLIC int DAEMON::startif_date (long date)
- {
- PROC *prc = process_find(path);
- int ret = 0;
- if (prc == NULL){
- if (date > 0){
- ret = start();
- }
- }else if (date <= 0){
- ret = stop();
- }else if (date > prc->getstarttime()){
- ret = restart();
- }
- return ret;
- }
-
-
- /*
- start the daemon if not active or restart it if needed.
- The daemon won't be started if not configured (Missing configuration
- file).
-
- The default behavior (virtual function) is to start it if it
- not already active.
-
- Return 0 = Was already active, 1 = started, 2 = not needed and
- -1 = some error.
- */
- PUBLIC VIRTUAL int DAEMON::startif()
- {
- PROC *prc = process_find (path);
- int ret = 0;
- if (prc == NULL){
- ret = start() != -1 ? 1 : -1;
- }
- return ret;
- }
- /*
- Return the name (not the path) of a daemon
- */
- PUBLIC const char *DAEMON::getname()
- {
- return name;
- }
- /*
- Return the next daemon in the link list or NULL.
- */
- PUBLIC DAEMON *DAEMON::getnext()
- {
- return next;
- }
- /*
- Return the path of a command or daemon.
- */
- PUBLIC const char *DAEMON::getpath()
- {
- return path != NULL ? path : (name != NULL ? name : "");
- }
- /*
- Return != 0 if the daemon exist on disk
- */
- PUBLIC int DAEMON::exist()
- {
- int ret = 0;
- if (path != NULL){
- struct stat st;
- ret = stat (path,&st) != -1;
- }
- return ret;
- }
- /*
- Return the standard args of a command or daemon.
- */
- PUBLIC const char *DAEMON::getargs()
- {
- return args != NULL ? args : "";
- }
-
-
- /*
- Return != 0 if the daemon or command is managed by netconf.
- The user may choose to manage some deamon with his own script.
- */
- PUBLIC int DAEMON::is_managed()
- {
- return managed;
- }
- /*
- Return != 0 if the daemon or command has been modified by the admin
- (either the path of the command or the arguments)
- */
- PUBLIC int DAEMON::is_overriden()
- {
- return override;
- }
-
- /*
- Set the managed flag.
- */
- PUBLIC void DAEMON::set_managed(int _managed)
- {
- managed = (char)_managed;
- }
- /*
- Set the override flag.
- */
- PUBLIC void DAEMON::set_override(int _over)
- {
- override = (char)_over;
- }
-
- /*
- Set the specs of the daemon
- */
- PUBLIC void DAEMON::setspec(const char *_path, const char *_args)
- {
- free (path);
- free (args);
- path = strdup(_path);
- args = strdup(_args);
- }
-
-
-
- /*
- Write one record of the ETC_CONF_DAEMONS file.
- */
- PUBLIC void DAEMON::write(FILE *fout)
- {
- if (isok()){
- fprintf (fout,"%s%s %s %s\n"
- ,managed ? "" : "!"
- ,name,path,args);
- }else{
- fprintf (fout,"%s\n",managed ? "" : "!");
- }
- }
-
-
-